// Matrix methods
//
function rasteriseMatrix(stdMtx) {
//  returns a rasterised format of the matrix object.
//
    var nRows: stdMtx.length,
        mCols: stdMtx[0].length,
        valArray = new Array(nRows*mCols);
        
    for ( var i = 0; i < nRows; i++ ) {
        for ( var j = 0; j < mCols; j++ ) {
            valArray[i*nRows + j] = stdMtx[i][j];
        }
    }
    
    return {
        valArray: valArray,
        nRows: nRows,
        mCols: mCols
    };
};

function stdMatrixMultiply(matA, matB) {
// Matricies in standard format:
//  mat = [[row 1....],
//         [row 2....],
//         .
//         [row n....]]
//
//  element at row i, col j is accessed thus: mat[i][j]
//
//  matA is an n X m matrix  (n rows by m columns)
//  matB is an k X l matrix  (k rows bt l columns)
//  if m != k then multiplication is not possible, return null
//  else return a n X l matrix
//  
    var n = matA.length,  // get no. of rows, n
        m = matA[0].length, // get no. of colums, m
        
        k = matB.length,
        l = matB[0].length;

    if (m != k) return null;
    
    var vRow, vCol, val = new Array(n), v;
    
    // multipy
    for (vRow = 0; vRow < n; vRow++) {
        val[vRow] = new Array(l);
        
        for (vCol = 0; vCol < l; vCol++) {
            v = 0;
            
            for (iCtr = 0; iCtr < n; iCtr++ ) {
                v = v + matA[vRow][iCtr] * matB[iCtr][vCol];
            }
            val[vRow][vCol] = v;
        }
    }
    
    return val;
}

function rasterMatrixMultiply(matA, matB) {
// Matricies in 'rasterised' format.
// Simple tests have shown this method to be 4 to 5 times faster than
// with matricies in standard format.
//
// Matrix object structure:
//  {
//      valArray: [],   // flat array to hold the nRows X mCols values
//      nRows: <num>,  // number of rows
//      mCols: <num>    // number of colums
//  }
//
//  element at row i, col j is accessed thus: valArray[i*nRows + j]
//
    if (matA.mCols != matB.nRows) return null;
    
    // for ease of typing and readability:
    var aMtx = matA.valArray, bMtx = matB.valArray,
        vRows = aRows = matA.nRows, vCols = bCols = matB.mCols,
        aCols = matA.mCols, bRows = matB.nRows,
        vR, vC, iCtr, vIdx, v,
        val = new Array(vRows*vCols);
    
    for (vR = 0; vR < vRows; vR++) {
        for (vC = 0; vC < vCols; vC++) {
            vIdx = vR * vCols + vC;
            v = 0;
            
            for (iCtr = 0; iCtr < aCols; iCtr++) {
                v = v + aMtx[vR*aCols +iCtr] * bMtx[iCtr*bCols +vC];
            }
            val[vIdx] = v;
        }
    }

    return {
        valArray: val,
        nRows: vRows,
        mCols: vCols
    };
}